package com.app.core.mvc.returnvalue;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.app.core.mvc.result.Result;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.core.MethodParameter;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.AsyncHandlerMethodReturnValueHandler;
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletResponse;

/**
 * @author 00351634
 * @version 1.0
 * @date 2024/9/29 14:37
 * @description: HandlerMethodReturnValueHandler实现类，给加了ResultRespBody的类或方法，统一封装成Result
 */
public class ResultRespBodyHandleReturnValue implements HandlerMethodReturnValueHandler, AsyncHandlerMethodReturnValueHandler {
    @Override
    public boolean isAsyncReturnValue(Object o, MethodParameter returnType) {
        return supportsReturnType(returnType);
    }

    @Override
    public boolean supportsReturnType(MethodParameter returnType) {
        ResultRespBody resultRespBodyInClass = returnType.getMethod().getDeclaringClass().getAnnotation(ResultRespBody.class);
        ResultRespBody resultRespBodyInMethod = returnType.getAnnotatedElement().getAnnotation(ResultRespBody.class);
        boolean resultRespBodyInClassExist = ObjectUtil.isNotEmpty(resultRespBodyInClass);
        boolean resultRespBodyInMethodExist = ObjectUtil.isNotEmpty(resultRespBodyInMethod);
        boolean resultRespBodyInClassEnabled = resultRespBodyInClassExist ? resultRespBodyInClass.enabled() : false;
        boolean resultRespBodyInMethodEnabled = resultRespBodyInMethodExist ? resultRespBodyInMethod.enabled() : false;
        return !((!resultRespBodyInClassExist && !resultRespBodyInMethodExist)
                || (resultRespBodyInMethodExist && !resultRespBodyInMethodEnabled)
                || (resultRespBodyInClassExist && !resultRespBodyInClassEnabled));
    }

    @Override
    public void handleReturnValue(Object o, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
        mavContainer.setRequestHandled(true);
        HttpServletResponse response = webRequest.getNativeResponse(HttpServletResponse.class);
        response.setContentType("application/json;charset=utf-8");
        ResultRespBody resultRespBodyInClass = returnType.getMethod().getDeclaringClass().getAnnotation(ResultRespBody.class);
        ResultRespBody resultRespBodyInMethod = returnType.getAnnotatedElement().getAnnotation(ResultRespBody.class);
        SerializerFeature[] defaultSerializerFeature = {
                SerializerFeature.DisableCircularReferenceDetect
        };
        /**
         * 替换注解中的序列化格式
         */
        if (ObjectUtil.isNotEmpty(resultRespBodyInClass) && ObjectUtil.isNotEmpty(resultRespBodyInClass.serializerFeature())) {
            defaultSerializerFeature = resultRespBodyInClass.serializerFeature();
        }
        if (ObjectUtil.isNotEmpty(resultRespBodyInMethod) && ObjectUtil.isNotEmpty(resultRespBodyInMethod.serializerFeature())) {
            defaultSerializerFeature = resultRespBodyInMethod.serializerFeature();
        }
        Class<?> parameterType = returnType.getParameterType();
        if (IPage.class.isAssignableFrom(parameterType)) {
            response.getWriter().write(JSON.toJSONString(Result.success((IPage) o), defaultSerializerFeature));
        } else {
            response.getWriter().write(JSON.toJSONString(Result.success(o), defaultSerializerFeature));
        }
    }
}
